package com.skyline.energy.provider.gwhalin;

import java.util.HashMap;
import java.util.Map;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
import com.skyline.energy.cache.Cache;
import com.skyline.energy.cache.CacheManager;
import com.skyline.energy.exception.CacheUnreachableException;
import com.skyline.energy.utils.CommonUtils;

public class MemcachedManager implements CacheManager {
	private final Map<String, MemcachedCache> clientPool = new HashMap<String, MemcachedCache>();
	private static final long DEFAULT_IDLE = 1000 * 60 * 60 * 6;
	
	private String[] servers;
	private Integer[] weights;
	private int initConn = 1;
	private int minConn = 1;
	private int maxConn = 100;
	private long maxIdle = DEFAULT_IDLE;
	private int maintSleep = 30;
	private boolean nagle = false;
	private int readTimeout = 3000; //3 secs
	private int connectTimeout = 0; //no time out
	
	public void setServers(String[] servers) {
		this.servers = servers;
	}
	
	public void setWeights(Integer[] weights) {
		this.weights = weights;
	}
	
	public void setInitConn(int initConn) {
		this.initConn = initConn;
	}

	public void setMinConn(int minConn) {
		this.minConn = minConn;
	}

	public void setMaxConn(int maxConn) {
		this.maxConn = maxConn;
	}

	public void setMaxIdle(long maxIdle) {
		this.maxIdle = maxIdle;
	}

	public void setMaintSleep(int maintSleep) {
		this.maintSleep = maintSleep;
	}

	public void setNagle(boolean nagle) {
		this.nagle = nagle;
	}

	public void setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	@Override
	public Cache getCache(String poolName) {
		String upperCase = poolName.toUpperCase();
		SockIOPool pool = SockIOPool.getInstance(upperCase);
		if(!pool.isInitialized()) {
			try {
				initializePool(pool);
			} catch (Exception e) {
				throw new CacheUnreachableException("Can't create Memcached Instance");
			}
			
		}
		
		return initializeClient(upperCase);
	}

	public void initializePool(SockIOPool pool) throws Exception {
		CommonUtils.assertNotNull(servers, "servers can not be null");
		pool.setServers(servers);
		if(weights != null) {
			pool.setWeights(weights);
		}
		pool.setInitConn(initConn);
		pool.setMinConn(minConn);
		pool.setMaxConn(maxConn);
		pool.setMaxIdle(maxIdle);

		pool.setMaintSleep(maintSleep);

		pool.setNagle(nagle);
		pool.setSocketTO(readTimeout);
		pool.setSocketConnectTO(connectTimeout);

		// initialize the connection pool
		pool.initialize();
	}
	
	public MemcachedCache initializeClient(String poolName) {
		MemcachedCache cache = clientPool.get(poolName);
		if(cache == null) {
			//I don't know why binary protocol is invalide in my pc, so just use tcp ascii; 
			MemCachedClient client = new MemCachedClient(poolName, true, false); 
			cache = new MemcachedCache(client);
		}
		return cache;
	}

	
}
